﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;

using Idlesoft.Cli;
using TestApp;

namespace CliTests
{
	/// <summary>
	///This is a test class for CliAttributeAttributeTest and is intended
	///to contain all CliAttributeAttributeTest Unit Tests
	///</summary>
	[TestClass()]
	public class CliAttributeAttributeTest
	{
		public const string FILE = "config.xml";
		public const string TITLE = "title";
		public const string DESCRIPTION = "description";
		public const FlagTypes FLAG_TYPES = FlagTypes.Default;

		public static readonly string[] PERSON_ARGS = new string[] { "--name", "scott", "--age", "37", "--pets", "penny", "triton" };
		public static readonly string[] CALC_ARGS = new string[] { "--numbers", "1", "2", "3", "--op", "+" };
		public static readonly object[] CALC_PARAMS = new object[] { "MyCalc" };
		public const string XML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<OptionalTarget Name=\"scott\" Age=\"37\" />";

		private TestContext testContextInstance;

		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		///</summary>
		public TestContext TestContext
		{
			get { return testContextInstance; }
			set { testContextInstance = value; }
		}

		public TCliVirtue PrepareVirtue<TCliVirtue>(string methodName, Type targetType)
			where TCliVirtue : class, ICliAttribute
		{
			TCliVirtue virtue = default(TCliVirtue);
			var member = targetType.GetMember(methodName).First();
			virtue = Attribute.GetCustomAttribute(member, typeof(TCliVirtue)) as TCliVirtue;
			virtue.MemberInfo = member;
			return virtue;
		}

		#region Additional test attributes
		// 
		//You can use the following additional attributes as you write your tests:
		//
		//Use ClassInitialize to run code before running the first test in the class
		//[ClassInitialize()]
		//public static void MyClassInitialize(TestContext testContext)
		//{
		//}
		//
		//Use ClassCleanup to run code after all tests in a class have run
		//[ClassCleanup()]
		//public static void MyClassCleanup()
		//{
		//}
		//
		//Use TestInitialize to run code before running each test
		//[TestInitialize()]
		//public void MyTestInitialize()
		//{
		//}
		//
		//Use TestCleanup to run code after each test has run
		//[TestCleanup()]
		//public void MyTestCleanup()
		//{
		//}
		//
		#endregion

		/// <summary>
		///A test for Required
		///</summary>
		[TestMethod()]
		public void RequiredFalseTest()
		{
			bool expected = false;
			var virtue = new CliAttributeAttribute();
			bool actual = virtue.Required;
			Assert.AreEqual(expected, actual);
		}

		/// <summary>
		///A test for Required
		///</summary>
		[TestMethod()]
		public void RequiredTrueTest()
		{
			bool expected = true;
			var virtue = new CliAttributeAttribute();
			virtue.Required = expected;
			bool actual = virtue.Required;
			Assert.AreEqual(expected, actual);
		}

		/// <summary>
		///A test for Option
		///</summary>
		[TestMethod()]
		public void OptionTrueTest()
		{
			bool expected = true;
			var virtue = PrepareVirtue<CliAttributeAttribute>("Op", typeof(Calculator));
			bool actual = virtue.Option;
			Assert.AreEqual(expected, actual);
		}

		/// <summary>
		///A test for Option
		///</summary>
		[TestMethod()]
		public void OptionFalseTest()
		{
			bool expected = false;
			var virtue = PrepareVirtue<CliAttributeAttribute>("Op", typeof(Calculator));
			virtue.Required = true;
			bool actual = virtue.Option;
			Assert.AreEqual(expected, actual);
		}

		/// <summary>
		///A test for BuiltIn
		///</summary>
		[TestMethod()]
		public void BuiltInTrueTest()
		{
			bool expected = true;
			var virtue = PrepareVirtue<CliAttributeAttribute>("Help", typeof(CliBuilder));
			bool actual = virtue.BuiltIn;
			Assert.AreEqual(expected, actual);
		}

		/// <summary>
		///A test for BuiltIn
		///</summary>
		[TestMethod()]
		public void BuiltInFalseTest()
		{
			bool expected = false;
			var virtue = PrepareVirtue<CliAttributeAttribute>("Op", typeof(Calculator));
			bool actual = virtue.BuiltIn;
			Assert.AreEqual(expected, actual);
		}

		/// <summary>
		///A test for IsAssigned
		///</summary>
		[TestMethod()]
		public void IsAssignedTrueTest()
		{
			bool expected = true;
			var target = new Person();
			var virtue = PrepareVirtue<CliAttributeAttribute>("Name", typeof(Person));
			target.Name = "scott";
			bool actual = virtue.IsAssigned(target);
			Assert.AreEqual(expected, actual);
		}

		/// <summary>
		///A test for IsAssigned
		///</summary>
		[TestMethod()]
		public void IsAssignedFalseTest()
		{
			bool expected = false;
			var target = new Person();
			var virtue = PrepareVirtue<CliAttributeAttribute>("Name", typeof(Person));
			bool actual = virtue.IsAssigned(target);
			Assert.AreEqual(expected, actual);
		}

		/// <summary>
		///A test for CliElementAttribute Constructor
		///</summary>
		[TestMethod()]
		public void CliElementAttributeConstructorTest()
		{
			string[] expected = new string[] { "-n", "--name" };
			CliAttributeAttribute target = new CliAttributeAttribute(expected);
			string[] actual = target.Flags;
			Assert.AreEqual(expected, actual);
		}
	}
}
